<?php

class Form extends HTMLElement
{
	/**
	 * 
	 *
	 * @var bool
	 */
	public $errorsUnderFields = true;
	
	/**
	 * 
	 *
	 * @var array
	 */
	private $elements = array();
	
	/**
	 * 
	 *
	 * @var array
	 */
	private $elementNames = array();
	
	/**
	 * 
	 *
	 * @var array
	 */
	private $elementDescriptions = array();
	
	/**
	 * 
	 *
	 * @var array
	 */
	private $htmlSorted = array();
	
	/**
	 * use POST or GET
	 * @var string
	 */
	private $method;
	
	/**
	 * 
	 * @var string
	 */
	private $action;
	
	/**
	 * 
	 * Contains all the elements's errors
	 * @var array
	 */
	private $errors = array();
	
	/**
	 * 
	 * Show a submit button
	 * @var boolean
	 */
	private $showSubmitBtn = true;
	
	/**
	 * 
	 * The submit button's name in the form data 
	 * @var unknown_type
	 */
	private $submitBtnName = 'save';
	
	/**
	 * The submit button's caption
	 *
	 * @var unknown_type
	 */
	private $submitBtnValue = 'opslaan';
	
	public function __construct($action = null, $method = 'post')
	{
		$this->action = $action;
		$this->method = strtolower($method);
	}
	

	
	/**
	 *
	 * @param string $html
	 */
	public function addHTML($html)
	{
		$index = count($this->elements);
		if(null == $this->htmlSorted[$index])
		{
			$this->htmlSorted[$index] = $html;
		}
		else 
		{
			$this->htmlSorted[$index] .= $html;
		}
	}
		
	public function addElement(HTMLElement $element, $description = '')
	{
		$this->elements[] = $element;
		$this->elementNames[] = $element->getName();
		$this->elementDescriptions[$element->getName()] = $description;
	}
	
	public function showSubmitButton()
	{
		$this->showSubmitBtn = true;
	}
	
	public function setSubmitName($name)
	{
		$this->submitBtnName = $name;
	}
	
	public function setSubmitButtonLabel($value)
	{
		$this->submitBtnValue = $value;
	}
	
	public function getSubmitName()
	{
		return $this->submitBtnName;
	}
	
	public function hideSubmitButton()
	{
		$this->showSubmitBtn = false;
	}
	
	public function validate()
	{
		$completed = true;
		foreach ($this->elements as $element)
		{
			if($element instanceof Validatable)
			{
				if(!($element->validate()))
				{
					$description = $this->elementDescriptions[$element->getName()];
					$this->errors[$element->getName()] =  $description .' '. $element->getError();
					$this->hasErrors = true;
					$completed = false;
				}
			}
		}
		return $completed;
	}	
	
	public function clearValues()
	{
		foreach ($this->elements as $element)
		{
			if($element instanceof Validatable)
			{
				$element->clear();
			}
		}
	}

	/**
	 * 
	 * @return bool
	 */
	public function hasErrors()
	{
		$this->hasErros;
	}
	
	/**
	 * 
	 * @return bool
	 */
	public function isPosted()
	{
		if($this->method == 'post')
		{
			$useArray = $_POST;			
		}
		else
		{
			$useArray = $_GET;
		}		
		return $useArray[$this->submitBtnName] == $this->submitBtnValue;
	}
	
	public function getErrors()
	{
		return $this->errors;
	}
	
	public function getElements()
	{
		return $this->elements;
	}
	
	public function getHTML()
	{
		
					
		
		$html = '<form method="'.$this->method.'"';
		if(null != $this->action)
		{
			$html .= ' action="'.$this->action.'"';
		}
		$html .= '>';
		
	
		
		$table = new Table();
		$errorTable = new Table();
		
		foreach ($this->elements as $element)
		{		
			$description = $this->elementDescriptions[$element->getName()];
			$fieldRow = '<label>'.$description . '</label><br />'. $element->getHTML();
			
			if($element instanceof Validatable)
			{
				if($this->errors[$element->getName()])
				{
					$errorTable->addRow(array($description .' '. $element->getError()));
					if($this->errorsUnderFields)
					{
						$fieldRow .= '<div class="form_error">Dit '.$element->getError().'</div>'; 
					}
				}
			}
			$table->addRow(array($fieldRow));
		}
		
		$buttonRow = array();
		
		if(true == $this->showSubmitBtn)
		{
			$btnSubmit = new Button($this->submitBtnName, $this->submitBtnValue);
			$buttonRow[] = $btnSubmit->getHTML();
		}	

		if(0 < count($buttonRow))
		{
			$table->addRow($buttonRow);
		}
		$html .= $table->getHTML();
		$html .= "\n";
		$html .= '</form>';
		return $html;
	}
	
}

?>